/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2006
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.commons.view;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

import br.ufmg.dees.insane.commons.InsaneProperties;
import br.ufmg.dees.insane.commons.command.Command;
import br.ufmg.dees.insane.commons.command.CommandHolder;

/**
 * A class representing the main window on the screen and the manager of the program.<br>
 * All users' processes come through this class.<br>
 * It's used to manage the whole program in order to have an efficient kind of consistence.
 *
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @version 1.0
 * @since November 2003
 */
public abstract class Interface extends JFrame implements ActionListener {
    
	protected static final long serialVersionUID = 1L;
	protected InsaneProperties properties;
	
	protected JDesktopPane desktop = new JDesktopPane();
	protected JMenuBar menuBar = new JMenuBar();
	protected JPanel toolPanel = new JPanel();
	
	protected ArrayList views = new ArrayList();
    protected int internalFramesCount = 0;
    protected ModelList modelList = new ModelList();
    
	//  For internationalization
	protected Locale currentLocale;
	protected ResourceBundle bundle;
	
    /**
     * The constructor method.
     */
    public Interface(){
    	currentLocale = getLocale();
    	bundle = ResourceBundle.getBundle("br.ufmg.dees.insane.langPack.InsaneLangPack", currentLocale);
    	desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
    };
    
    /**
     * The constructor method.
     */
    public Interface(Locale locale){
    	currentLocale = locale;
    	bundle = ResourceBundle.getBundle("br.ufmg.dees.insane.langPack.InsaneLangPack", currentLocale);
    	desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
    };
	
    /** Returns the properties.
	*@return The properties.
	*/
    public InsaneProperties getProperties(){
    	return properties;
    };
    
    /** Sets the initial Interface. */
    public abstract void setInitialInterface();
    
    /** Adds a Command to the undoList.*/
    public abstract void addToUndo(Command cmd);
    
    /** Adds a Command to the redoList.*/
    public abstract void addToRedo(Command cmd);
	
    /** Disables the redo command.*/
    public abstract void nothingToRedo();
    
    /** Disables the undo command.*/
    public abstract void nothingToUndo();
    
    /**
     * Sets the Status Bar message.
     * @param str The text to be shown
     */
    public abstract void setMessage(String str);
	
    /**
     * Appends a message to the output panel.
     * @param str The message to be appended.
     */
    public void addOutputText(String str) {}
    
    /** Method which executes the desired action to each command.*/
    public void actionPerformed(ActionEvent evt) {
        CommandHolder obj = (CommandHolder)evt.getSource();
		obj.getCommand().execute();
    }
	
	/**Returns this interface's ResourceBundle
	*@return This interface's ResourceBundle
	*/
	public ResourceBundle getResourceBundle(){
		return bundle;
	}

	/**Sets this interface's Locale
	*@param loc The Locale to be set
	*/
	public void setLocale(Locale loc){
		currentLocale = loc;
		bundle = ResourceBundle.getBundle("br.ufmg.dees.insane.langPack.InsaneLangPack", currentLocale);
		properties = new InsaneProperties(bundle);
	}
	
	/**Gets this interface's Locale
	*@return The current Locale
	*/
	public Locale getLocale(){
		return currentLocale;
	}
	
	/**
	 * The method return the modelList.
	 * @return Returns The modelList.
	 */
	public ModelList getModelList() {
		return modelList;
	}
	/**
	 * The method set the field modelList from the parameter modelList.
	 * @param modelList The modelList to set.
	 */
	public void setModelList(ModelList modelList) {
		this.modelList = modelList;
	}
	/** Updates all labels to current locale ones.*/
	public void setAllLabels(){};
	
	/** Adds a Command to the undoList.
	 * @param cmd a the desired command
	 **/
	public void addInternalFrame(JInternalFrame F) {
		this.repaint();
		F.pack();
		F.setVisible(true);
		F.setIconifiable(true);
		F.setPreferredSize(new Dimension(desktop.getWidth(),desktop.getHeight()));
		F.setSize(this.getWidth()/2-5,this.getHeight()/2-this.menuBar.getHeight()-(int)(this.toolPanel.getHeight()/1.5));
		F.setLocation(0,0);
		
		if(internalFramesCount==0){
			F.setLocation(0,0);
			internalFramesCount++;
		}else if(internalFramesCount==1){
			F.setLocation(this.getWidth()/2-5,0);
			internalFramesCount++;
		}else if(internalFramesCount==2){
			F.setLocation(0,this.getHeight()/2-this.menuBar.getHeight()-(int)(this.toolPanel.getHeight()/1.5));
			internalFramesCount++;
		}else if(internalFramesCount==3){
			F.setLocation(this.getWidth()/2-5,this.getHeight()/2-this.menuBar.getHeight()-(int)(this.toolPanel.getHeight()/1.5));
			internalFramesCount = 0;
		}
		
		F.setResizable(true);
		F.setMaximizable(true);
		
		desktop.add(F);
		if(F instanceof InternalInterface){
			((InternalInterface)F).setOwner(this);
		}
		desktop.setVisible(true);
		desktop.repaint();
		desktop.updateUI();
		
	}
	
	/**
	 * Returns the JDesktopPane of this Interface.
	 * @return The JDesktopPane of this Interface.
	 */
	public JDesktopPane getDesktop(){
		return desktop;	
	}
	
}
